package com.ddxz.tool.http;

import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * class description
 *
 * @author 朱宗刚
 * @version 1.0.0
 * @date 2020/9/16
 */

public class DdxzHttpClient {
    protected static OkHttpClient getHttpClient() {
        return getHttpClient(DEFAULT_POOL_SIZE, CALL_TIMEOUT);
    }

    protected static OkHttpClient getHttpClient(Integer poolMaxSize) {
        return getHttpClient(poolMaxSize, CALL_TIMEOUT);
    }

    protected static OkHttpClient getHttpClient(Long timeout) {
        return getHttpClient(DEFAULT_POOL_SIZE, timeout);
    }

    protected static synchronized OkHttpClient getHttpClient(Integer poolMaxSize, Long timeout) {
        String key = timeout + "_" + poolMaxSize;
        if(instance.containsKey(key)) {
            return instance.get(key);
        } else {
            OkHttpClient rst = new OkHttpClient.Builder()
                    .callTimeout(timeout, TimeUnit.MILLISECONDS)
                    .connectTimeout(timeout, TimeUnit.MILLISECONDS)
                    .readTimeout(timeout, TimeUnit.MILLISECONDS)
                    .writeTimeout(timeout, TimeUnit.MILLISECONDS)
                    .connectionPool(new ConnectionPool(poolMaxSize, timeout, TimeUnit.MILLISECONDS))
                    .build();
            instance.put(key, rst);
            return rst;
        }
    }

    protected static OkHttpClient getHttpsClient() {
        return getHttpsClient(CALL_TIMEOUT, DEFAULT_POOL_SIZE);
    }

    protected static OkHttpClient getHttpsClient(Long timeout) {
        return getHttpsClient(timeout, DEFAULT_POOL_SIZE);
    }

    protected static OkHttpClient getHttpsClient(Integer poolMaxSize) {
        return getHttpsClient(CALL_TIMEOUT, poolMaxSize);
    }

    protected static synchronized OkHttpClient getHttpsClient(Long timeout, Integer poolMaxSize) {
        String key = timeout + "_" + poolMaxSize + "_S";
        if(instance.containsKey(key)) {
            return instance.get(key);
        } else {
            OkHttpClient rst = new OkHttpClient.Builder()
                    .callTimeout(timeout, TimeUnit.MILLISECONDS)
                    .connectTimeout(timeout, TimeUnit.MILLISECONDS)
                    .readTimeout(timeout, TimeUnit.MILLISECONDS)
                    .writeTimeout(timeout, TimeUnit.MILLISECONDS)
                    .sslSocketFactory(createSSLSocketFactory(), new TrustAllCerts())
                    .connectionPool(new ConnectionPool(poolMaxSize, timeout, TimeUnit.MILLISECONDS))
                    .build();
            instance.put(key, rst);
            return rst;
        }
    }

    private static SSLSocketFactory createSSLSocketFactory() {
        SSLSocketFactory ssfFactory = null;
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, new TrustManager[]{new TrustAllCerts()}, new SecureRandom());
            ssfFactory = sc.getSocketFactory();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return ssfFactory;
    }

    private static Map<String, OkHttpClient> instance = new HashMap<>();

    protected static final long CALL_TIMEOUT = 60000;

    protected static final int DEFAULT_POOL_SIZE = 5;
}
